// 上传文件控制器
const multer = require('multer');
const { v4: uuidv4 } = require('uuid');
const minioClient = require('../config/minio');
require('dotenv').config();

// 存储桶名称
const BUCKET_NAME = process.env.MINIO_BUCKET || 'myblog';

// 配置multer使用内存存储
const storage = multer.memoryStorage();
const upload = multer({ storage: storage });

/**
 * 检查存储桶是否存在，不存在则创建
 */
async function ensureBucketExists() {
  try {
    const exists = await minioClient.bucketExists(BUCKET_NAME);
    if (!exists) {
      await minioClient.makeBucket(BUCKET_NAME);
      // 设置公共读取权限，使文件可以通过URL直接访问
      await minioClient.setBucketPolicy(
        BUCKET_NAME,
        JSON.stringify({
          Version: '2012-10-17',
          Statement: [
            {
              Effect: 'Allow',
              Principal: { AWS: ['*'] },
              Action: ['s3:GetObject'],
              Resource: [`arn:aws:s3:::${BUCKET_NAME}/*`]
            }
          ]
        })
      );
    }
  } catch (error) {
    console.error('检查存储桶失败:', error);
    throw error;
  }
}

/**
 * 生成文件访问URL
 * @param {string} objectName - 对象名称
 * @returns {string} 文件URL
 */
function generateFileUrl(objectName) {
  const protocol = process.env.MINIO_USESSL === 'true' ? 'https' : 'http';
  const endpoint = process.env.MINIO_ENDPOINT || 'localhost';
  const port = process.env.MINIO_PORT || '9000';
  return `${protocol}://${endpoint}:${port}/${BUCKET_NAME}/${objectName}`;
}

/**
 * 上传文件
 * @desc 上传文件到MinIO存储桶
 * @access Public
 */
const uploadFile = [upload.single('file'), async (req, res) => {
  try {
    // 确保存储桶存在
    await ensureBucketExists();

    // 检查是否有文件
    if (!req.file) {
      return res.status(400).json({ success: false, message: '请上传文件' });
    }

    // 获取用户指定的文件名或生成唯一文件名
    let fileName = req.body.filename;
    const fileExtension = req.file.originalname.split('.').pop();

    if (!fileName) {
      // 如果没有提供文件名，生成唯一文件名
      fileName = `${uuidv4()}.${fileExtension}`;
    } else {
      // 如果提供了文件名但没有扩展名，添加原文件的扩展名
      if (!fileName.includes('.')) {
        fileName = `${fileName}.${fileExtension}`;
      }
    }

    // 上传文件到MinIO
    await minioClient.putObject(
      BUCKET_NAME,
      fileName,
      req.file.buffer,
      req.file.size,
      { 'Content-Type': req.file.mimetype }
    );

    // 生成访问URL
    const fileUrl = generateFileUrl(fileName);

    res.status(200).json({
      success: true,
      message: '文件上传成功',
      data: {
        fileName,
        url: fileUrl
      }
    });
  } catch (error) {
    console.error('上传文件失败:', error);
    res.status(500).json({ success: false, message: '服务器错误', error: error.message });
  }
}];

/**
 * 删除文件
 * @desc 根据文件名删除MinIO存储桶中的文件
 * @access Public
 */
const deleteFile = async (req, res) => {
  try {
    // 从URL参数获取文件名
    const fileName = req.params.filename;

    // 验证文件名是否提供
    if (!fileName) {
      return res.status(400).json({ success: false, message: '请提供文件名' });
    }

    // 检查存储桶是否存在
    const bucketExists = await minioClient.bucketExists(BUCKET_NAME);
    if (!bucketExists) {
      return res.status(404).json({ success: false, message: '存储桶不存在' });
    }

    // 删除文件
    await minioClient.removeObject(BUCKET_NAME, fileName);

    res.status(200).json({
      success: true,
      message: '文件删除成功',
      data: {
        fileName
      }
    });
  } catch (error) {
    console.error('删除文件失败:', error);
    res.status(500).json({ success: false, message: '服务器错误', error: error.message });
  }
};

/**
 * 获取文件列表
 * @desc 获取MinIO存储桶中的文件列表，支持分页和搜索
 * @access Public
 * @param {number} [params.page=1] - 当前页码 (可选, 默认为 1)
 * @param {number} [params.limit=10] - 每页数量 (可选, 默认为 10)
 * @param {string} [params.search] - 模糊搜索文件名称
 */
const getFileList = async (req, res) => {
  try {
    // 检查存储桶是否存在
    const bucketExists = await minioClient.bucketExists(BUCKET_NAME);
    if (!bucketExists) {
      return res.status(404).json({ success: false, message: '存储桶不存在' });
    }

    // 获取分页和搜索参数
    const page = parseInt(req.query.page, 10) || 1;
    const limit = parseInt(req.query.limit, 10) || 10;
    const search = req.query.search;
    const offset = (page - 1) * limit;

    const allFiles = [];

    // 列出存储桶中的所有对象
    const objectsStream = minioClient.listObjectsV2(BUCKET_NAME, '', true);

    await new Promise((resolve, reject) => {
      objectsStream.on('data', (obj) => {
        // 如果有搜索条件，则过滤文件名
        if (search) {
          if (obj.name.toLowerCase().includes(search.toLowerCase())) {
            allFiles.push({
              fileName: obj.name,
              url: generateFileUrl(obj.name),
              lastModified: obj.lastModified,
              size: obj.size
            });
          }
        } else {
          allFiles.push({
            fileName: obj.name,
            url: generateFileUrl(obj.name),
            lastModified: obj.lastModified,
            size: obj.size
          });
        }
      });

      objectsStream.on('error', reject);
      objectsStream.on('end', resolve);
    });

    // 按最后修改时间降序排序
    allFiles.sort((a, b) => new Date(b.lastModified) - new Date(a.lastModified));

    // 计算总文件数
    const total = allFiles.length;
    
    // 计算分页后的文件
    const paginatedFiles = allFiles.slice(offset, offset + limit);

    res.status(200).json({
      success: true,
      message: '获取文件列表成功',
      data: {
        files: paginatedFiles,
        pagination: {
          currentPage: page,
          totalPages: Math.ceil(total / limit),
          totalItems: total,
          itemsPerPage: limit
        }
      }
    });
  } catch (error) {
    console.error('获取文件列表失败:', error);
    res.status(500).json({ success: false, message: '服务器错误', error: error.message });
  }
};

module.exports = {
  uploadFile,
  deleteFile,
  getFileList
};